{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Aria2.Notification
  ( NotificationType (..),
    Notification,
    notificationType,
    gid,
  )
where

import Aria2.GID (GID)
import Data.Aeson ((.:), FromJSON (..), withObject)
import Data.Text (Text, stripPrefix)

data NotificationType
  = OnDownloadStart
  | OnDownloadPause
  | OnDownloadStop
  | OnDownloadComplete
  | OnDownloadError
  | OnBtDownloadComplete
  deriving stock (Eq, Show)

data Notification = Notification !NotificationType {-# UNPACK #-} !GID
  deriving stock (Eq, Show)

notificationType :: Notification -> NotificationType
notificationType (Notification t _) = t

gid :: Notification -> GID
gid (Notification _ g) = g

instance FromJSON Notification where
  parseJSON = withObject "Notification" go
    where
      go obj = do
        method :: Text <- obj .: "method"
        nt <- case stripPrefix "aria2." method of
          Nothing -> fail ("Not a valid Aria2 method: " <> show method)
          Just methodName -> case methodName of
            "onDownloadStart" -> pure OnDownloadStart
            "onDownloadPause" -> pure OnDownloadPause
            "onDownloadStop" -> pure OnDownloadStop
            "onDownloadComplete" -> pure OnDownloadComplete
            "onDownloadError" -> pure OnDownloadError
            "onBtDownloadComplete" -> pure OnBtDownloadComplete
            t -> fail ("Not a valid Aria2 notification: " <> show t)
        Notification nt <$> obj .: "gid"
